﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using InterfacesTransformation;
using System.IO;
using DTO;

namespace MyGroupReducing
{
    public partial class SizeGroupReducingPlugin : IGroupReducingUserControl, IGroupReducing
    {
        public SizeGroupReducingPlugin()
        {
            InitializeComponent();
        }

        private IHost pluginHost = null;
        public IHost PluginHost
        {
            get
            {
                return pluginHost;
            }
            set
            {
                this.pluginHost = value;
            }
        }

        private string pluginName = "Refine Groups";
        public string PluginName
        {
            get
            {
                return this.pluginName;
            }
        }

        private string pluginDescription = "Refine groups of webpages by their size.";

        public string PluginDescription
        {
            get { return pluginDescription; }
            set { pluginDescription = value; }
        }

        public IGroupReducingUserControl PluginUserControl
        {
            get
            {
                return this;
            }
        }

        public void Initialize()
        {
        }

        public void PluginDispose()
        {
        }

        public List<List<int>> Reducing(List<List<int>> groups)
        {
            return GroupReducing(
                groups, 
                Convert.ToInt32(numericUpDownMinNumOfElements.Value), 
                textBoxLocalRepositoryPath.Text, 
                Convert.ToInt32(numericUpDownPercentageElements.Value)
                );
        }

        /// <summary>
        /// Reducing the number of webpages in groups.
        /// </summary>
        /// <param name="groups">List of original groups</param>
        /// <param name="LocalRepositoryPath">Path of the local repository path that contains all webpages.</param>
        /// <param name="MaxNumberOfItems">The maximum number of items of a group that will be left untouched.</param>
        /// <param name="PercentageOfRemainingPage">The percentage of remaining webpages in a reduced group.</param>
        /// <returns>List of reduced groups that contains webpage IDs</returns>
        public List<List<int>> GroupReducing(List<List<int>> groups, int MaxNumberOfItems, string LocalRepositoryPath, int PercentageOfRemainingPage)
        {
            List<KeyValuePair<int, long>> webpageFiles = new List<KeyValuePair<int, long>>();
            List<Webpage> allWebpages = DAL.WebpageDAL.GetWebpagesNoChecking();

            foreach (List<int> curGroup in groups)
            {
                if (curGroup.Count > MaxNumberOfItems)
                {
                    int numberOfRemainingPage = PercentageOfRemainingPage * curGroup.Count / 100;
                    if (numberOfRemainingPage < 2)
                        numberOfRemainingPage = 2;
                    webpageFiles = new List<KeyValuePair<int, long>>();
                    foreach (int curPageID in curGroup)
                    {
                        try
                        {
                            FileInfo fi = new FileInfo(LocalRepositoryPath + "\\" + allWebpages[curPageID - 1].Path);
                            webpageFiles.Add(new KeyValuePair<int, long>(curPageID, fi.Length));
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }
                    webpageFiles.Sort(new SortByFileSize());
                    List<int> tempGroup = new List<int>();
                    for (int i = 0; i < numberOfRemainingPage; i++)
                    {
                        tempGroup.Add(webpageFiles[i].Key);
                    }
                    curGroup.Clear();
                    curGroup.AddRange(tempGroup);
                }
            }
            return groups;
        }

        public class SortByFileSize : IComparer<KeyValuePair<int, long>>
        {
            public int Compare(KeyValuePair<int, long> file1, KeyValuePair<int, long> file2)
            {
                return (file2.Value.CompareTo(file1.Value));
            }
        }

        #region GUI Event Handlers
        private void buttonBrowse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog myFolderBrowserDlg = new FolderBrowserDialog();
            myFolderBrowserDlg.Description = "Select the Local Repository folder";
            if (myFolderBrowserDlg.ShowDialog() == DialogResult.OK)
            {
                textBoxLocalRepositoryPath.Text = string.Empty;
                textBoxLocalRepositoryPath.Text = myFolderBrowserDlg.SelectedPath;
            }
        }
        #endregion
    }
}
